<html>
<head>
<title>脚本控件参考</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<style>
body{font-size:13px;}
table{border-collapse:collapse;border:1px solid #ccc;font-size:14px; width:80%;}
p.code{color:#629600;}
</style>
</head>
<body>

<h1>
	Microsoft ScriptControl 控件使用指南</h1>
<div id="content">
	<div>
		<p>
			随着动态网页的出现，脚本语言已经被越来越多的人认识、接受并撑握。在程序中加入对脚本的支持一方面可以最大限度的扩展程序的应用范围，另一方面也方便程序员利用现有脚本提供的一些特别的功能（如正则表达式等）。下面结合我个人的一点经验谈一谈这方面的应用。</p>
		<p>
			很显然要自己去实现一个脚本解释器是不现实的。好在已经有了可以复用的组件，那就是Microsoft ScriptControl。这是一个ActiveX控件，随Windows2000一起发布，如果要在2000以前的Windows中使用则需要安装该控件（可以到MS的网站上找到）。</p>
		<h2>
			ScriptControl接口</h2>
		<table border="1" cellpadding="0" cellspacing="0">
			<tbody>
				<tr>
					<td valign="top" width="115">
						<p>
							属性名称</p>
					</td>
					<td valign="top" width="88">
						<p>
							类型</p>
					</td>
					<td valign="top" width="365">
						<p>
							备注</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							AllowUI</p>
					</td>
					<td valign="top" width="88">
						<p>
							BOOL</p>
					</td>
					<td valign="top" width="365">
						<p>
							检测是否允许运行用户的接口元素。如果为False，则诸如消息框之类的界面元素不可见。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							CodeObject</p>
					</td>
					<td valign="top" width="88">
						<p>
							Object</p>
					</td>
					<td valign="top" width="365">
						<p>
							脚本暴露给宿主调用的对象。只读。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Modules</p>
					</td>
					<td valign="top" width="88">
						<p>
							Modules</p>
					</td>
					<td valign="top" width="365">
						<p>
							宿主提供给脚本的组件库模块。只读。（COM组件通常都是以对象收集的形式向用户提供可以留给用户二次开发的对象集合，每一个收集即一个Modules）</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Language</p>
					</td>
					<td valign="top" width="88">
						<p>
							String</p>
					</td>
					<td valign="top" width="365">
						<p>
							设置或获取脚本引擎解释的语言，例如：VBScript、JScript。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Name</p>
					</td>
					<td valign="top" width="88">
						<p>
							String</p>
					</td>
					<td valign="top" width="365">
						<p>
							脚本引擎的名称。只读。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Procedures</p>
					</td>
					<td valign="top" width="88">
						<p>
							Procedures</p>
					</td>
					<td valign="top" width="365">
						<p>
							返回模块中定义的过程的集合</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							SitehWnd</p>
					</td>
					<td valign="top" width="88">
						<p>
							HWND</p>
					</td>
					<td valign="top" width="365">
						<p>
							在脚本中显示UI的父窗口句柄</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							State</p>
					</td>
					<td valign="top" width="88">
						<p>
							Enum</p>
					</td>
					<td valign="top" width="365">
						<p>
							设置或返回控件的状态，如果为0，控件只执行语句但不转发事件，为1则为加入的本控件接受的对象转发事件。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Timeout</p>
					</td>
					<td valign="top" width="88">
						<p>
							Long</p>
					</td>
					<td valign="top" width="365">
						<p>
							控件的执行脚本的超时值，－1表示不超时</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							UseSafeSubset</p>
					</td>
					<td valign="top" width="88">
						<p>
							BOOL</p>
					</td>
					<td valign="top" width="365">
						<p>
							设置或返回宿主程序是否关心安全。宿主程序的安全级别可以从此属性设置</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="115">
						<p>
							Error</p>
					</td>
					<td valign="top" width="88">
						<p>
							Error</p>
					</td>
					<td valign="top" width="365">
						<p>
							错误对象，发生错误时，此属性返回一个错误对象</p>
					</td>
				</tr>
			</tbody>
		</table>
		<p>
			&nbsp;</p>
		<table border="1" cellpadding="0" cellspacing="0">
			<tbody>
				<tr>
					<td valign="top" width="103">
						<p>
							方法名称</p>
					</td>
					<td valign="top" width="180">
						<p>
							参数</p>
					</td>
					<td valign="top" width="285">
						<p>
							功能</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							AddCode</p>
					</td>
					<td valign="top" width="180">
						<p>
							Code As String</p>
					</td>
					<td valign="top" width="285">
						<p>
							往脚本引擎中加入要执行的脚本</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							AddObject</p>
					</td>
					<td valign="top" width="180">
						<p>
							Name As String, Object As Object, [AddMembers As Boolean = False]</p>
					</td>
					<td valign="top" width="285">
						<p>
							往脚本引擎加入一个对象,以便在脚本中可以使用该对象提供的方法等。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							Eval</p>
					</td>
					<td valign="top" width="180">
						<p>
							Expression As String</p>
					</td>
					<td valign="top" width="285">
						<p>
							表达式求值</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							ExecuteStatement</p>
					</td>
					<td valign="top" width="180">
						<p>
							Statement As String</p>
					</td>
					<td valign="top" width="285">
						<p>
							解释并执行脚本语句</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							Reset</p>
					</td>
					<td valign="top" width="180">
						<p>
							&nbsp;</p>
					</td>
					<td valign="top" width="285">
						<p>
							丢弃所有的对象和代码，将State属性置0。</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="103">
						<p>
							Run</p>
					</td>
					<td valign="top" width="180">
						<p>
							ProcedureName As String, ParamArray Parameters() As Variant</p>
					</td>
					<td valign="top" width="285">
						<p>
							运行一个指定的过程</p>
					</td>
				</tr>
			</tbody>
		</table>
		<p>
			&nbsp;</p>
		<table border="1" cellpadding="0" cellspacing="0">
			<tbody>
				<tr>
					<td valign="top" width="139">
						<p>
							事件名称</p>
					</td>
					<td valign="top" width="429">
						<p>
							功能</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="139">
						<p>
							Error</p>
					</td>
					<td valign="top" width="429">
						<p>
							有错误发生时激发该事件</p>
					</td>
				</tr>
				<tr>
					<td valign="top" width="139">
						<p>
							TimeOut</p>
					</td>
					<td valign="top" width="429">
						<p>
							执行过程超时时发生</p>
					</td>
				</tr>
			</tbody>
		</table>
		<p>
			&nbsp;</p>
		<h2>
			一般使用方法</h2>
		<p>
			1、在程序中加入ScriptControl</p>
		<p>
			2、定义一个ScriptControl的实例</p>
		<p>
			3、调用AddCode等方法向脚本引擎中加入要执行的脚本。</p>
		<p>
			4、调用Run执行要执行的脚本函数。</p>
		<h2>
			宿主与脚本的通讯</h2>
		<p>
			1、&nbsp; 宿主调用脚本：这个过程比较简单，只要调用Run就可以将参数传递到脚本。</p>
		<p>
			2、&nbsp; 脚本调用宿主：在初始化过程中调用AddObject接口，将宿主的一个或多个对象暴露给脚本，这时就可以在脚本中调用宿主对象的方法。在VC++中这个对象不是普通的C++类，它必须支持自动化，在脚本中也只能调用对象中自动化接口（在VB中这个个程相对比较简单）。</p>
		<h2>
			脚本调试</h2>
		<p>
			任何人写的代码都不可能一次就很完美，但是脚本由于执行的位置特殊，调试方法也不一样。首先下载一个脚本调试器（我用的是Microsoft Script Debugger, 在MS网站有下载，另据说其它的如VJ＋＋也可以），安装以后在菜单上没有启动菜单。</p>
		<h3>
			调试器的启动</h3>
		<p>
			在一般的高级语言中都可以方便的设置断点，但是在启动脚本调试器以前如何开始调试呢？在IE中脚本出错会自动提示是否调试，还可以在脚本中加入中断代码（VBScript: Stop JavaScript: debugger）,但是在ScriptControl还需要修改一下注册表才可以，你需要将HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings下的JITDebug的值改为1（默认为0）</p>
	</div>
</div>
<p>
	&nbsp;</p>


</body>
</html>
